CSS 选择器

HTML中经常要 为 某些元素 指定 显示效果,比如 前景文字颜色是红色, 背景颜色是黑色, 字体是微软雅黑等。

那么CSS必须告诉浏览器:要 针对哪些元素 , 来使用这样的显示风格。

比如 , 下例中,为什么狮子老虎山羊会显示为红色呢?


<head>
  <style>
    .animal {color: red;}
  </style>
</head>

<body>    
  <div class="plant"><span>土豆</span></div>
  <div class="plant"><span>洋葱</span></div>

  <div class="animal"><span>狮子</span></div>
  <div class="animal"><span>老虎</span></div>
  <div class="animal"><span>山羊</span></div>
</body>

因为head里面用 CSS 样式,指定了 class 值为 animal 的元素,要显示为红色。

其中 .animal 就是 CSS 选择器(CSS Selector)

CSS 选择器 语法就是用来 选择 元素的。


所以,CSS 选择器 非常重要,它指定了 针对哪些元素 使用后面指定的样式。

根据 标签名

根据 标签(tag)名 选择元素的 CSS Selector 语法非常简单,直接写上标签名即可,

比如 要选择 所有的标签名为 p 的元素,就可以是这样

p {
  color: red
}

要选择 所有的标签名为 span 的元素,就可以是这样

span{
  color: green
}

根据 id 属性

根据id属性 选择元素 是在id号前面加上一个井号: #id值

比如,这样的HTML

<h1 id='news'>今日新闻</h1>
<p  style='color:green'>白月黑羽日活用户突破3万</p>

要选择 h1 元素,可以

#news {
  color: red
}

注意:

如果id 值为纯数字,比如

<h1 id='33'>今日新闻</h1>

不能使用 #33 这样的选择方法。


如果id 值有其它CSS选择关键字符,比如 . # > 等等

<h1 id='a.b'>今日新闻</h1>
<h1 id='a>b'>今日新闻</h1>

不能使用 #a.b #a>b 这样的选择方法。


那么如何选择,可以使用后面讲解的 根据属性选择 的方法

根据 class 属性

根据class属性 选择元素的语法是在 class 值 前面加上一个点: .class值

比如,这样的HTML

<h1 class='top-heading'>今日新闻</h1>
<p class="item-news byhy-news">白月黑羽日活用户突破3万</p>

要选择 h1 元素,可以

.top-heading {
  color: red
}

注意,上例中 p 元素 有 两个 class 属性, 要选择p元素,不能这样写

.item-news byhy-news {
  color: red
}

这样写的意思就变成了:选择 class为 item-news 的元素的内部 标签名为 byhy-news 的元素

只能通过其中一个来选择,比如

.item-news{
  color: red
}

或者

.byhy-news{
  color: red
}

选择 子元素 和 后代元素

HTML中, 元素 内部可以 包含其他元素

打开这个html链接, 对于如下的 HTML片段

<div id='container'>
    
    <div id='layer1'>
        <div id='inner11'>
            <span>内层11</span>
        </div>
        <div id='inner12'>
            <span>内层12</span>
        </div>
    </div>

    <div id='layer2'>
        <div id='inner21'>
            <span>内层21</span>
        </div>
    </div>
    
</div>

下面的一段话有些绕口, 请 大家细心 阅读:

id 为 container 的div元素 包含了 id 为 layer1layer2 的两个div元素。

这种包含是直接包含, 中间没有其他的层次的元素了。 所以 id 为 layer1layer2 的两个div元素 是 id 为 container 的div元素 的 子元素

而 id 为 layer1 的div元素 又包含了 id 为 inner11inner12 的两个div元素。 中间没有其他层次的元素,所以这种包含关系也是 子元素 关系

id 为 layer2 的div元素 又包含了 id 为 inner21 这个div元素。 这种包含关系也是 子元素 关系


而对于 id 为 container 的div元素来说, id 为 inner11inner12inner22 的元素 和 两个 span类型的元素 都不是 它的子元素, 因为中间隔了 几层。

虽然不是子元素, 但是 它们还是在 container 的内部, 可以称之为它 的 后代元素

后代元素也包括了子元素, 比如 id 为 layer1layer2 的两个div元素 也可以说 是 id 为 container 的div元素 的 子元素,同时也是后代元素


如果 元素2元素1 的 子元素, CSS Selector 选择子元素的语法是这样的

元素1 > 元素2

中间用一个大于号 (我们可以理解为箭头号)

注意,最终选择的元素是 元素2, 并且要求这个 元素2元素1 的子元素


也支持更多层级的选择, 比如

元素1 > 元素2 > 元素3 > 元素4

就是选择 元素1 里面的子元素 元素2 里面的子元素 元素3 里面的子元素 元素4 , 最终选择的元素是 元素4


如果 元素2元素1 的 后代元素, CSS Selector 选择后代元素的语法是这样的

元素1   元素2

中间是一个或者多个空格隔开

最终选择的元素是 元素2 , 并且要求这个 元素2元素1 的后代元素。


也支持更多层级的选择, 比如
元素1   元素2   元素3  元素4

最终选择的元素是 元素4


根据属性选择

id、class 都是web元素的 属性 ,因为它们是很常用的属性,所以css选择器专门提供了根据 id、class 选择的语法。

那么其他的属性呢?

比如

<a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>

里面根据 href选择,可以用css 选择器吗?

当然可以!

CSS 选择器支持通过任何属性来选择元素,语法是用一个方括号 []

比如要选择上面的a元素,就可以使用 [href="http://www.miitbeian.gov.cn"]

这个表达式的意思是,选择 属性href值为 http://www.miitbeian.gov.cn 的元素。


当然,前面可以加上标签名的限制,比如 div[class='SKnet'] 表示 选择所有 标签名为div,且class属性值为SKnet的元素。

属性值用单引号,双引号都可以。


根据属性选择,还可以不指定属性值,比如 [href] , 表示选择 所有 具有 属性名 为href 的元素,不管它们的值是什么。


CSS 还可以选择 属性值 包含 某个字符串 的元素

比如, 要选择a节点,里面的href属性包含了 miitbeian 字符串,就可以这样写

a[href*="miitbeian"]

还可以 选择 属性值 以某个字符串 开头 的元素

比如, 要选择a节点,里面的href属性以 http 开头 ,就可以这样写

a[href^="http"]

还可以 选择 属性值 以某个字符串 结尾 的元素

比如, 要选择a节点,里面的href属性以 gov.cn 结尾 ,就可以这样写

a[href$="gov.cn"]

如果一个元素具有多个属性

<div class="misc" ctype="gun">沙漠之鹰</div>

CSS 选择器 可以指定 选择的元素要 同时具有多个属性的限制,像这样 div[class=misc][ctype=gun]

验证 CSS Selector

我们怎么验证 CSS Selector 的语法是否正确选择了我们要选择的元素呢?

可以在浏览器 开发者工具栏 中验证。

比如我们使用Chrome浏览器, 打开这个链接

然后,按F12 打开 开发者工具栏

如果我们要验证 下面的表达式

#bottom > .footer2  a

能否选中 这个元素

<a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>

可以这样做:

点击 Elements 标签后, 同时按 Ctrl 键 和 F 键, 就会出现下图箭头处的 搜索框

我们可以在里面输入任何 CSS Selector 表达式 ,如果能选择到元素, 右边的的红色方框里面就会显示出类似 2 of 3 这样的内容。

of 后面的数字表示这样的表达式 总共选择到几个元素

of 前面的数字表示当前黄色高亮显示的是 其中第几个元素

上图中的 1 of 1 就是指 : CSS 选择语法 #bottom > .footer2 a

在当前网页上共选择到 1 个元素, 目前高亮显示的是第1个。

如果我们输入 .plant 就会发现,可以选择到3个元素


选择语法联合使用

CSS selector的另一个强大之处在于: 选择语法 可以 联合使用

请点击打开这个网址

比如, 我们要选择 网页 html 中的元素 <span class='copyright'>版权</span>

<div id='bottom'>
    <div class='footer1'>
        <span class='copyright'>版权</span>
        <span class='date'>发布日期:2018-03-03</span>
    </div>
    <div class='footer2'>
        <span>备案号
            <a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>
        </span>
    </div>        
</div>         

CSS selector 表达式 可以这样写:

div.footer1 > span.copyright

就是 选择 一个class 属性值为 copyright 的 span 节点, 并且要求其 必须是 class 属性值为 footer1 的 div节点 的子节点


也可以更简单:

.footer1 > .copyright

就是 选择 一个class 属性值为copyright 的节点(不限类型), 并且要求其 必须是 class 属性值为 footer1 的节点的 子节点


当然 这样也是可以的:

.footer1  .copyright

因为子元素同时也是后代元素


组选择

如果我们要 同时选择所有class 为 plant class 为 animal 的元素。怎么办?

这种情况,css选择器可以 使用 逗号 ,称之为 组选择 ,像这样

.plant , .animal

再比如,我们要同时选择所有tag名为div的元素 id为BYHY的元素,就可以像这样写

div,#BYHY

我们再看一个例子

打开这个网址 请点击打开这个网址

我们要选择所有 唐诗里面的作者和诗名, 也就是选择所有 id 为 t1 里面的 span 和 p 元素

我们是不是应该这样写呢?

#t1 > span,p

不行哦,这样写的意思是 选择所有 id 为 t1 里面的 span所有的 p 元素

只能这样写

#t1 > span , #t1 > p

按次序选择子节点

父元素的第n个子节点

我们可以指定选择的元素 是父元素的第几个子节点

使用 nth-child

比如,

请点击打开这个网址

对应的html如下,关键信息如下

<body>  
  <div id='t1'>
      <h3> 唐诗 </h3>
      <span>李白</span>
      <p>静夜思</p>
      <span>杜甫</span>
      <p>春夜喜雨</p>              
  </div>      
   
  <div id='t2'>
      <h3> 宋词 </h3>
      <span>苏轼</span>
      <p>赤壁怀古</p>
      <p>明月几时有</p>
      <p>江城子·乙卯正月二十日夜记梦</p>
      <p>蝶恋花·春景</p>
      <span>辛弃疾</span>
      <p>京口北固亭怀古</p>
      <p>青玉案·元夕</p>
      <p>西江月·夜行黄沙道中</p>
  </div>             
</body>

我们要选择 唐诗 和宋词 的第一个 作者,

也就是说 选择的是 第2个子元素,并且是span类型

所以这样可以这样写 span:nth-child(2)


如果你不加节点类型限制,直接这样写 :nth-child(2)

就是选择所有位置为第2个的所有元素,不管是什么类型


学员对nth-child的含义很容易产生误解,请点击这里,观看白月黑羽给实战班学员答疑讲解 nth-child

父元素的倒数第n个子节点

也可以反过来, 选择的是父元素的 倒数第几个子节点 ,使用 nth-last-child

比如:

p:nth-last-child(1)

就是选择第倒数第1个子元素,并且是p元素

父元素的第几个某类型的子节点

我们可以指定选择的元素 是父元素的第几个 某类型的 子节点

使用 nth-of-type

比如,

我们要选择 唐诗 和宋词 的第一个 作者,

可以像上面那样思考:选择的是 第2个子元素,并且是span类型

所以这样可以这样写 span:nth-child(2)


还可以这样思考,选择的是 第1个span类型 的子元素

所以也可以这样写 span:nth-of-type(1)

父元素的倒数第几个某类型的子节点

当然也可以反过来, 选择父元素的 倒数第几个某类型 的子节点

使用 nth-last-of-type

像这样

p:nth-last-of-type(2)

奇数节点和偶数节点

如果要选择的是父元素的 偶数节点,使用 nth-child(even)

比如

p:nth-child(even)

如果要选择的是父元素的 奇数节点,使用 nth-child(odd)

p:nth-child(odd)

如果要选择的是父元素的 某类型偶数节点,使用 nth-of-type(even)

如果要选择的是父元素的 某类型奇数节点,使用 nth-of-type(odd)

兄弟节点选择

相邻兄弟节点选择

上面的例子里面,我们要选择 唐诗 和宋词 的第一个 作者

还有一种思考方法,就是选择 h3 后面紧跟着的兄弟节点 span。

这就是一种 相邻兄弟 关系,可以这样写 h3 + span

表示元素 紧跟关系的 是 加号

后续所有兄弟节点选择

如果要选择是 选择 h3 后面所有的兄弟节点 span,可以这样写 h3 ~ span



更多CSS选择器的介绍,可以参考CSS 选择器参考手册

所有元素

选择所有元素可用使用 星号

比如

/* 设置所有元素的颜色为绿色 */
* { color : green; } 

/* class 为 greenworld 元素中所有的下级元素颜色为绿色 */
.greenworld * { color : green !important; }

下面是一个具体的例子

<head>
    <style>
       .greenworld * { color : green !important; }
    </style>
</head>

<body>
    <div class='greenworld'>
    <a href='//byhy.net/' style='color:red'> 白月黑羽</a>
    <p>文本1</p>
    <p>文本2</p>
    </div>
</body>